package com.easyOrder.service.common;

import com.easyOrder.core.context.ThreadWebContextHolder;
import com.easyOrder.core.context.WebSession;
import com.easyOrder.core.context.WebSessionManager;
import com.easyOrder.core.exception.api.InvalidPasswordException;
import com.easyOrder.core.exception.api.UserNameNotExistException;
import com.easyOrder.core.utils.WebUtils;
import com.easyOrder.dao.LoginLogsMapper;
import com.easyOrder.dao.UserMapper;
import com.easyOrder.model.*;
import com.easyOrder.param.user.LoginParameter;
import com.easyOrder.param.user.LoginResult;
import com.easyOrder.service.user.UserBranchService;
import com.easyOrder.service.user.UserService;
import com.google.common.base.Preconditions;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * Created by liutao on 2017/7/15.
 */
@Service
public class LoginService {

    @Autowired
    LoginLogsMapper loginLogMapper;

    @Autowired
    WebSessionManager webSessionManager;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserService userService;

    @Autowired
    private CommonService commonService;

    @Autowired
    HttpServletRequest request;

    @Autowired
    private UserBranchService userBranchService;


    /**
     * 根据人员信息登录
     *
     * @param loginParameter
     * @return
     */
    public LoginResult loginByUser(LoginParameter loginParameter) {
        loginParameter.setCode(loginParameter.getCode().trim());
        loginParameter.setPassword(loginParameter.getPassword().trim());
        loginValidate(loginParameter);
        User user = userService.findUserByCode(loginParameter.getCode());
        Preconditions.checkArgument(user!=null, "此账户人员信息已被禁用或删除");
//        UserBranch userBranch = userBranchService.findByUserId(user.getId(), null);
//        Preconditions.checkArgument(userBranch!=null, "此账户人员没有门店，请联系管理员");
        WebSession session = createLoginUserSession(user, loginParameter.getDeviceId());
        updateLoginInfo(loginParameter, user, session);
        return buildBuyerLoginResult(loginParameter, user, session);
    }

    /**
     * 初始化登录信息
     *
     * @param user
     * @param session
     * @return
     */
    public LoginResult initLoginResult(User user, WebSession session) {
        LoginResult loginResult = new LoginResult();
        loginResult.setUserCode(user.getCode());
        loginResult.setSessionId(session.getId());
        loginResult.setLoginDate(session.getStartTime());
        loginResult.setTenantId(session.getTenantId());
        loginResult.setEmployeeId(session.getEmployeeId());
        loginResult.setEmployeeName(session.getEmployeeName());
        loginResult.setUserId(user.getId());
        loginResult.setUserName(user.getName());
        loginResult.setIconPath(null == user.getIconPath() ? "" : user.getIconPath());
        loginResult.setTenantName(session.getTenantName());
        loginResult.setBranchId(null == session.getBranchId() ? 0L : Long.valueOf(session.getBranchId()));
        loginResult.setBranchName(session.getBranchName());
        loginResult.setDepartmentId(null == session.getDepartmentId() ? 0L : Long.valueOf(session.getDepartmentId()));
        loginResult.setDepartmentName(session.getDepartmentName());
        loginResult.setDataLimit(session.getDataScope());
        if (session.getDataScopeTypeId() == null) {
            loginResult.setDataLimitTypeId(3);
        } else {
            loginResult.setDataLimitTypeId(session.getDataScopeTypeId());
        }
        loginResult.setMobile(user.getMobile());
        loginResult.setFirstLogin(null == user.getLoginDate());
        loginResult.setTenantManager(session.getTenantManager());
        loginResult.setBranchManager(session.getBranchManager());
        return loginResult;
    }

    /**
     * 添加登录日志
     *
     * @param loginParameter
     */
    private void addLoginLog(LoginParameter loginParameter) {
        if (null == loginParameter) {
            return;
        }
        LoginLogs loginLogs = new LoginLogs();
        loginLogs.setDeviceId(loginParameter.getDeviceId());
        loginLogs.setIp(WebUtils.Http.getIpAddr(request));
        loginLogs.setLatitude(loginParameter.getLatitude());
        loginLogs.setLoginClient(loginParameter.getClient());
        loginLogs.setLoginDate(new Date());
        loginLogs.setLoginType(loginParameter.getClientTypeId());
        loginLogs.setLongitude(loginParameter.getLongitude());
        loginLogs.setUserName(loginParameter.getCode());
        loginLogMapper.insertSelective(loginLogs);
    }

    /**
     * 构造卖家家登录信息
     *
     * @param loginParameter
     * @param user
     * @param session
     * @return
     */
    public LoginResult buildBuyerLoginResult(LoginParameter loginParameter,
                                             User user, WebSession session) {
        LoginResult loginResult = initLoginResult(user, session);
        //userService.populateEmployeeFunctionAndMenus(loginResult);
        //setOperationBranchIds(loginResult);
        addLoginLog(loginParameter);

        loginResult.setSecretKey(session.getSecretKey());
        return loginResult;
    }

    /**
     * 更新登录信息
     *
     * @param loginParameter
     * @param user
     * @param session
     */
    private void updateLoginInfo(LoginParameter loginParameter, User user,
                                 WebSession session) {
        User modifiedUser = new User();
        modifiedUser.setId(user.getId());
        if (null != user.getLoginDate()) {
            modifiedUser.setLoginDate(session.getStartTime());
        }
        if (null != loginParameter.getClientTypeId()) {
            modifiedUser.setLoginClientTypeId(loginParameter.getClientTypeId());
        }
        modifiedUser.setLoginClient(loginParameter.getClient());
        modifiedUser.setSession(session.getId());
        modifiedUser.setPasswordExpiredDate(user.getPasswordExpiredDate());
        modifiedUser.setDataLimit(user.getDataLimit());
        modifiedUser.setDataLimitTypeId(user.getDataLimitTypeId());
        userMapper.updateByPrimaryKeySelective(modifiedUser);
    }

    /**
     * 创建登录用户会话信息
     *
     * @param user
     * @param deviceId
     * @return
     */
    private WebSession createLoginUserSession(User user, String deviceId) {
        WebSession webSession = new WebSession();
        webSession.setTenantId(user.getTenantId());
        webSession.setUserId(user.getId());
        webSession.setUserName(user.getName());
        webSession.setDataScope(user.getDataLimit());
        webSession.setDataScopeTypeId(null == user.getDataLimitTypeId() ? 3 : user.getDataLimitTypeId());
        webSession.setDeviceId(deviceId);
        webSession.setMobile(user.getMobile());
        webSession.setFirstLogin(user.getLoginDate() == null);
        if (null == webSession.getBranchId()) {
            webSession.setBranchTypeId(0);
        }
        webSession.setTenantManager(null != user.getIsSuperUser() && user.getIsSuperUser().equals(1));

        webSessionManager.add(webSession);
        ThreadWebContextHolder.getContext().setWebSession(webSession);
        return webSession;
    }

    /**
     * 登录验证
     *
     * @param loginParameter
     */
    private void loginValidate(LoginParameter loginParameter) {
        Preconditions.checkArgument(null != loginParameter);
        Preconditions.checkArgument(StringUtils.isNotBlank(loginParameter.getCode()), "用户名不能为空");
        Preconditions.checkArgument(StringUtils.isNotBlank(loginParameter.getPassword()), "密码不能为空");

        UserExample userExample = new UserExample();
        UserExample.Criteria criteria = userExample.createCriteria()
                .andCodeEqualTo(loginParameter.getCode().trim())
                .andStatusIdEqualTo(1);
        if (userMapper.countByExample(userExample) <= 0) {
            throw new UserNameNotExistException();
        }
        loginParameter.setPassword(commonService.encryptPassword(loginParameter.getPassword().trim()));
        criteria.andPasswordEqualTo(loginParameter.getPassword());
        if (userMapper.countByExample(userExample) <= 0) {
            throw new InvalidPasswordException();
        }
    }
}
